<template>

	<view class="preview">
		<!-- #ifndef H5 -->
		<tn-nav-bar fixed :alpha="true">{{title}}</tn-nav-bar>
		<!-- #endif -->
		<view style="background-color: black;color: white;">
			<view style="padding: 20rpx;">
				<!-- <demo-title title="颜料" :contentPadding="false"></demo-title> -->
				<view style="display: flex; align-items: center;">
					<view style="padding: 0 10rpx 0 0;">模型：</view>
					<tn-input v-model="models.name" type="select" placeholder="请选择模型"
						@click="models.show = true"></tn-input>
					<view @tap="openModel()">
						<text class="tn-icon-help tn-padding-sm tn-text-xl"> </text>
						<text>详情</text>
					</view>
				</view>

				<view style="display: flex; align-items: center;">
					<view style="padding: 0 10rpx 0 0;">编码器：</view>
					<tn-input v-model="vae.name" type="select" placeholder="请选择采样器" @click="vae.show = true"></tn-input>
					<view @tap="openModel(form.vae_hash,'vae')">
						<text class="tn-icon-help tn-padding-sm tn-text-xl"> </text>
						<text>详情</text>
					</view>
				</view>

				<view style="display: flex; align-items: center;">
					<view style="padding: 0 10rpx 0 0;">采样器：</view>
					<tn-input v-model="sampler.name" type="select" placeholder="请选择采样器"
						@click="sampler.show = true"></tn-input>
					<view @tap="openModel(sampler.name,'sampler')">
						<text class="tn-icon-help tn-padding-sm tn-text-xl"> </text>
					</view>
					
					<view style="padding: 0 10rpx 0 20rpx;">Seed：</view>
					<view  style="width: 150rpx;">
						<tn-input v-model="form.seed" type="number" placeholder="默认完全随机,不晓得就么动" ></tn-input>
					</view>
				</view>
				<!-- <demo-title title="言语" :contentPadding="false"></demo-title> -->
				<view class="content tn-flex tn-flex-direction-row tn-flex-col-center" style="padding: 10rpx 0;"
					v-for="(item,index) in paramList" :key="index">
					<view class="content__title" style="padding: 0 10rpx 0 0;">{{item.desc}}：</view>
					<view class="content__data tn-flex-1"
						style="background-color: #0d0d0d; border-radius: 20rpx;padding: 10rpx;"
						v-if="item.type == 'string'">
						<tn-input type="textarea" :maxLength="9999" inputAlign="center" :clearable="false"
							@input="getLoraTag(item.name,item.value)" :placeholder="item.default"
							v-model="item.value"></tn-input>
					</view>
					<view class="content__data tn-flex-1" v-else-if="item.type == 'slider'">
						<tn-slider v-model="item.value" :step="item.step" :min="item.min" :max="item.max"></tn-slider>
						<view class="tn-margin-left-sm">{{item.value}}</view>
					</view>
				</view>


				<view style="display: flex; align-items: center;">
					<view style="padding: 0 10rpx 0 0;">微调模型(lora)：</view>
					<view v-for="(tagItem, tagIndex) in loraTags" :key="tagIndex"
						style="border: 1px #888 solid;padding: 6rpx 12rpx;border-radius: 20rpx;background-color: #1d1d1d;margin-right: 10rpx;">
						<view>
							<text>{{ tagItem.model }}</text>:
							<text>{{ tagItem.weight }}</text>
							<text class="tn-icon-help" @tap="openModel(tagItem.model,'lora')"> </text>
						</view>
					</view>
					<view style="border: 1px #888 solid;padding: 6rpx 12rpx;border-radius: 20rpx;margin-right: 10rpx;">
						<view @tap="addLora">
							<text class="tn-icon-add "> </text>
						</view>
					</view>
				</view>
				<!-- <demo-title title="画幅" :contentPadding="false"></demo-title> -->
				<!-- <view style="display: flex;align-items: center;margin: 30upx 0;">
					<view style="flex: 1;" @tap="wh='z'">
						<view class="wh-item-z" :class="wh=='z'?'wh-select':''">
							<view style="width: 120rpx; text-align: center;">正</view>
						</view>
					</view>
					<view style="flex: 1;" @tap="wh='s'">
						<view class="wh-item-s" :class="wh=='s'?'wh-select':''">
							<view style="width: 120rpx; text-align: center;">竖</view>
						</view>
					</view>
					<view style="flex: 1;" @tap="wh='h'">
						<view class="wh-item-h" :class="wh=='h'?'wh-select':''">
							<view style="width: 120rpx; text-align: center;">横</view>
						</view>
					</view>
				</view> -->

				<!-- <view style="display: flex; align-items: center;">
					<view style="padding: 0 10rpx 0 0;">实时模式：</view>
					<tn-switch :disabled="true"></tn-switch>
				</view>
				<view >如果有服务器实时在线并且满足生成条件，增加任务权重，进入实时渲染模式</view> -->

				<view style="padding: 10rpx 0 0 0;" class="tn-text-center">
					<!-- <tn-button :shadow="true" width="30%" height="100rpx" backgroundColor="#222" fontColor="#FFFFFF"
							margin="10rpx 0" @click="submitTask(true)">单图预览</tn-button>
					<text class="tn-padding"></text> -->
					<tn-button :shadow="true" width="50%" height="100rpx" backgroundColor="#222" fontColor="#FFFFFF"
						margin="10rpx 0" @click="submitTask()">提交任务</tn-button>
				</view>
				
				<view style="padding: 50rpx 0;">
					<view>
						<text>Tips:</text>
						<view class="tn-padding">
							<text>任务会在后台队列处理,一次生成12张图片以及对应的故事以及标题。所有生成图片都会经过双重审核，图片看不见就说明违规被吞了</text>
						</view>
						<view class="tn-padding">
							<text>中文的提示词会翻译后拼接再英文提示词后面,图片尺寸不是越大越好，而是要看模型来，有些模型大图会导致画面重复</text>
						</view>
						<view class="tn-padding">
							<text>感谢 “Stable Diffusion” 以及 “ChatGLM” 的开源 </text>
						</view>
						<view class="tn-padding">
							<text>感谢 “Helsinki-NLP” 的开源翻译模型，https://huggingface.co/Helsinki-NLP/opus-mt-zh-en </text>
						</view>

					</view>
					<view>

					</view>
				</view>
			</view>


			<tn-select v-model="models.show" labelName="name" valueName="hash" mode="single" :list="models.list"
				@confirm="modelsSelectConfirm"></tn-select>

			<tn-select v-model="vae.show" labelName="name" valueName="hash" mode="single" :list="vae.list"
				@confirm="vaeSelectConfirm"></tn-select>

			<tn-select v-model="sampler.show" labelName="name" valueName="name" mode="single" :list="sampler.list"
				@confirm="samplerSelectConfirm"></tn-select>

		</view>
	</view>
</template>

<script>
	import demoTitle from '@/libs/components/demo-title.vue'
	import {
		forEach
	} from '../../tuniao-ui/libs/luch-request/utils';

	export default {
		name: 'ComponentsInput',
		components: {
			demoTitle
		},
		created(e) {},
		onLoad(e) {
			console.log('e', e)

			this.$tn.http.post('/api/drawing/get_config_list').then(res => {
				if (res) {
					this.models.list = res.models;
					console.log('A')
					this.sampler.list = res.samplers;
					console.log('B')
					this.vae.list = res.vae;
					if (e.id) {
						var img = uni.getStorageSync('img_' + e.id)
						// 初始化
						let model = res.models.find(item => item.hash === img.model_hash);
						this.form.model_hash = img.model_hash
						this.models.name = model.name
						let vae = res.vae.find(item => item.hash === img.vae_hash);
						if (vae) {
							this.form.vae_hash = img.vae_hash
							this.vae.name = vae.name
						} else {
							this.form.vae_hash = this.vae.list[0].hash
							this.vae.name = this.vae.list[0].name
						}
						this.form.sampler_name = img.sampler_name ? img.sampler_name : this.sampler.list[0].name
						console.log('img', img)
						this.paramList.forEach((item) => {
							switch (item.name) {
								case 'prompt':
									item.value = img.prompt
									this.getLoraTag('prompt', img.prompt)
									break
								case 'cfg_scale':
									item.value = img.cfg_scale
									break
								case 'height':
									item.value = img.height
									break
								case 'width':
									item.value = img.width
									break
								case 'negative_prompt':
									item.value = img.negative_prompt
									break
								case 'zh_prompt':
									item.value = img.zh_prompt
									break
								case 'zh_negative_prompt':
									item.value = img.zh_negative_prompt
									break
								default:
									break
							}
						})
					}
				}

			}).catch(err => {
				console.error('err', err)
				uni.showModal({
					content: '服务器已关闭或失联',
				})
			});

		},
		data() {
			return {
				form: {
					model_hash: '',
					vae_hash: '',
					sampler_name: '',
					width: 640,
					height: 960,
					seed:-1
				},
				models: {
					list: [],
					name: "",
					show: false
				},

				sampler: {
					list: [],
					name: "Euler a",
					show: false
				},
				vae: {
					list: [],
					name: "Automatic",
					show: false
				},
				wh: 's',
				task_id: '',
				param_key: '',
				loraTags: [{
					model: 'test',
					weight: 1.2
				}],
				paramList: [{
						name: 'steps',
						desc: "采样步数",
						type: "slider",
						max: 50,
						min: 5,
						value: 20,
					},
					{
						name: 'cfg_scale',
						desc: "提示词引导系数",
						type: "slider",
						max: 30,
						step: 0.5,
						min: 1,
						value: 7,
					},
					{
						name: 'zh_prompt',
						desc: "中文提示词",
						type: "string",
						default: "魔法师，耳机，粉色头发，蓝色衣服，红色鞋子，白色面具",
						value: "",
					},
					{
						name: 'zh_negative_prompt',
						desc: "中文反向词",
						type: "string",
						default: "纯色背景",
						value: "",
					}, {
						name: 'prompt',
						desc: "英文提示词",
						type: "string",
						default: "1gril",
						value: "",
					},
					{
						name: 'negative_prompt',
						desc: "英文反向词",
						type: "string",
						default: "nsfw",
						value: "",
					},
					{
						name: 'width',
						desc: "图片宽度",
						type: "slider",
						default: "368",
						max: 1024,
						min: 64,
						step: 8,
						value: 640,
					}, {
						name: 'height',
						desc: "图片高度",
						type: "slider",
						default: "368",
						max: 1024,
						step: 8,
						min: 64,
						value: 960,
					},

				],
			}
		},
		methods: {
			submitTask(preview = false) {
				let param = this.form

				
				// switch (this.wh) {
				// 	case 'h':
				// 		param['height'] = 640
				// 		param['width'] = 960
				// 		break;
				// 	case 's':
				// 		param['height'] = 960
				// 		param['width'] = 640
				// 		break;
				// 	default:
				// 		param['height'] = 640
				// 		param['width'] = 640
				// 		break;
				// }
				
				this.paramList.forEach((item) => {
					param[item.name] = item.value ? item.value : null
				})
				console.log('param', param)
				// return
				if(preview){
					param['preview'] = true
					this.$tn.http.post('/api/drawing/add_task', param).then(res => {
						if(res.server){
							
						}else{
							uni.showModal({
								content: '当前没有任何服务器在线，无法完成预览',
							})
						}
					}).catch(err => {
						console.error('err', err)
						uni.showModal({
							content: '服务器发生错误或已关闭或失联',
						})
					});
				}else{
					this.$tn.http.post('/api/drawing/add_task', param).then(res => {
						uni.showModal({
							title: '造图任务已提交',
							content: '当前在你前面队列有' + res.waits + '个任务，ps:我把自己服务器关机的话这队列就不会动'
						});
					}).catch(err => {
						console.error('err', err)
						uni.showModal({
							content: '服务器发生错误或已关闭或失联',
						})
					});
				}
				
			},
			openModel(key = null, model = 'model') {
				if (key == '') {
					uni.showToast({
						icon: 'none',
						title: '当前模型没有详情'
					})
					return
				}
				if (key == null) {
					key = this.form.model_hash
				}
				uni.navigateTo({
					url: '/pages/moyi/Model?key=' + key + '&type=' + model,
				})
			},
			addLora() {
				uni.showToast({
					icon: 'none',
					title: '暂无此功能'
				})
			},
			getLoraTag(name, str) {
				const loraRegex = /<lora:([^>]+)>/g;
				switch (name) {
					case 'prompt':
						let match;
						let loraTags = [];

						while ((match = loraRegex.exec(str)) !== null) {
							let tagContent = match[1];
							let [model, weight] = tagContent.split(':');
							loraTags.push({
								model: model,
								weight: parseFloat(weight)
							});
						}
						this.loraTags = loraTags
						break;
					default:
						break;
				}
			},
			// 模型列选择器
			modelsSelectConfirm(event) {
				console.log('event', event)
				this.form.model_hash = event[0]['value']
				this.models.name = event[0]['label']
			},
			// 模型列选择器
			vaeSelectConfirm(event) {
				console.log('event', event)
				this.form.vae_hash = event[0]['value']
				this.vae.name = event[0]['label']
			},
			// 模型列选择器
			samplerSelectConfirm(event) {
				console.log('event', event)
				this.form.sampler_name = event[0]['value']
				this.sampler.name = event[0]['label']
			},
		}
	}
</script>


<style lang="scss" scoped>
	.wh {
		&-select {
			background-color: #3d3d3d;
		}

		&-item {
			&-z {
				margin: auto;
				border: 2px #aaa solid;
				border-radius: 10rpx;
				align-items: center;
				display: flex;
				width: 120rpx;
				height: 120rpx;
			}

			&-s {
				margin: auto;
				border: 2px #aaa solid;
				border-radius: 10rpx;
				align-items: center;
				display: flex;
				width: 80rpx;
				height: 120rpx;
			}

			&-h {
				margin: auto;
				border: 2px #aaa solid;
				border-radius: 10rpx;
				align-items: center;
				display: flex;
				width: 120rpx;
				height: 80rpx;
			}

		}
	}


	.components-input {
		background-color: $tn-bg-gray-color;
		min-height: 100vh;

		.content {
			background-color: #FFFFFF;

			&__title {
				padding: 30rpx;
			}

			&__data {
				margin: 10rpx 0;
				margin-right: 30rpx;
			}
		}
	}
</style>